﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace SL4.CustomControls
{

    // 刷新事件的事件参数
    public class ReloadEventArgs : EventArgs
    {
        public SortDescriptionCollection SortDescriptions { get; set; }
    }

   // 为了实现排序功能，所以需要实现 ICollectionView 接口（仅实现其中的排序功能部分）
    // 为了集合具有改变通知的功能，所以需要继承自 ObservableCollection<T>
    //http://www.cnblogs.com/webabcd/archive/2010/10/27/1862119.html Url
    public class SortableCollectionView<T> : ObservableCollection<T>, ICollectionView
    {
        public SortableCollectionView()
        {
            _currentItem = null;
            _currentPosition = -1;
        }

        protected override void ClearItems()
        {
            base.ClearItems();

            // 触发 CurrentChanging 事件
            OnCurrentChanging();
        }



        public bool CanFilter
        {
            get { return false; }
        }

        public bool CanGroup
        {
            get { return false; }
        }

        // 允许通过 SortDescriptions 属性进行排序
        public bool CanSort
        {
            get { return true; }
        }

        public System.Globalization.CultureInfo Culture { get; set; }

        // 当前项
        private object _currentItem;
        public object CurrentItem
        {
            get { return _currentItem; }
        }

        // 当前项的索引
        private int _currentPosition;
        public int CurrentPosition
        {
            get { return _currentPosition; }
        }

        public Predicate<object> Filter { get; set; }

        public ObservableCollection<GroupDescription> GroupDescriptions
        {
            get { return null; }
        }

        public ReadOnlyObservableCollection<object> Groups
        {
            get { return null; }
        }

        // 当前项是否超出了集合的末尾
        public bool IsCurrentAfterLast
        {
            get
            {
                if (!IsEmpty)
                    return CurrentPosition >= base.Count;

                return true;
            }
        }

        // 当前项是否超出了集合的开头
        public bool IsCurrentBeforeFirst
        {
            get
            {
                if (!IsEmpty)
                    return CurrentPosition < 0;

                return true;
            }
        }

        // 集合是否为空
        public bool IsEmpty
        {
            get { return base.Count == 0; }
        }

        // System.ComponentModel.SortDescription 类型对象的集合，其用于描述集合中的数据的排序方式
        private SortDescriptionCollection _sortDescriptions;
        public SortDescriptionCollection SortDescriptions
        {
            get
            {
                if (_sortDescriptions == null)
                    _sortDescriptions = new SortDescriptionCollection();

                return _sortDescriptions;
            }
        }

        public System.Collections.IEnumerable SourceCollection
        {
            get { return this; }
        }

        // 当前项更改后所触发的事件
        public event EventHandler CurrentChanged;

        // 当前项准备更改之前所触发的事件
        public event CurrentChangingEventHandler CurrentChanging;

        // 指定的项是否属于此集合
        public bool Contains(object item)
        {
            return Contains((T)item);
        }

        // 延迟刷新
        public IDisposable DeferRefresh()
        {
            return new DeferRefreshHelper(() => Refresh());
        }
        private class DeferRefreshHelper : IDisposable
        {
            private Action _callback;

            public DeferRefreshHelper(Action callback)
            {
                _callback = callback;
            }

            public void Dispose()
            {
                _callback();
            }
        }

        // 将指定项设置为当前项
        public bool MoveCurrentTo(object item)
        {
            if (object.Equals(CurrentItem, item) && (item != null || IsCurrentInView))
                return IsCurrentInView;

            int index = base.IndexOf((T)item);

            return MoveCurrentToPosition(index);
        }

        // 将第一项设置为当前项
        public bool MoveCurrentToFirst()
        {
            return MoveCurrentToPosition(0);
        }

        // 将最后一项设置为当前项
        public bool MoveCurrentToLast()
        {
            return MoveCurrentToPosition(base.Count - 1);
        }

        // 将当前项的下一项设置为当前项
        public bool MoveCurrentToNext()
        {
            return CurrentPosition < base.Count && MoveCurrentToPosition(CurrentPosition + 1);
        }

        // 将指定位置的项设置为当前项
        public bool MoveCurrentToPosition(int position)
        {
            if (position < -1 || position > base.Count)
                throw new Exception("参数“position”不在范围内");

            if (position != CurrentPosition)
            {
                bool isCurrentAfterLast = IsCurrentAfterLast;
                bool isCurrentBeforeFirst = IsCurrentBeforeFirst;

                OnCurrentChanging();
                ChangeCurrentToPosition(position);
                OnCurrentChanged();

                if (IsCurrentAfterLast != isCurrentAfterLast)
                    OnPropertyChanged("IsCurrentAfterLast");
                if (IsCurrentBeforeFirst != isCurrentBeforeFirst)
                    OnPropertyChanged("IsCurrentBeforeFirst");

                OnPropertyChanged("CurrentPosition");
                OnPropertyChanged("CurrentItem");
            }

            return IsCurrentInView;
        }

        // 将当前项的上一项设置为当前项
        public bool MoveCurrentToPrevious()
        {
            return CurrentPosition >= 0 && MoveCurrentToPosition(CurrentPosition - 1);
        }

        public event EventHandler<ReloadEventArgs> Reload;
        // 刷新集合
        public void Refresh()
        {
            if (Reload != null)
                Reload(this, new ReloadEventArgs() { SortDescriptions = SortDescriptions });
        }

        protected virtual void OnCurrentChanged()
        {
            if (CurrentChanged != null)
                CurrentChanged(this, EventArgs.Empty);
        }

        protected virtual void OnCurrentChanging(CurrentChangingEventArgs args)
        {
            if (args == null)
                throw new Exception("参数“args”不能为 null");

            if (CurrentChanging != null)
                CurrentChanging(this, args);
        }

        protected void OnCurrentChanging()
        {
            _currentPosition = -1;

            OnCurrentChanging(new CurrentChangingEventArgs(false));
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }



        // 获取集合内指定位置的对象
        private object GetItemAt(int index)
        {
            if (index >= 0 && index < base.Count)
                return this[index];

            return null;
        }

        // 当前项是否在集合的范围之内
        private bool IsCurrentInView
        {
            get { return CurrentPosition >= 0 && CurrentPosition < base.Count; }
        }

        // 将指定位置的项设置为当前项
        private void ChangeCurrentToPosition(int position)
        {
            if (position < 0)
            {
                _currentItem = null;
                _currentPosition = -1;
            }
            else if (position >= base.Count)
            {
                _currentItem = null;
                _currentPosition = base.Count;
            }
            else
            {
                _currentItem = this[position];
                _currentPosition = position;
            }
        }




    }
}





